/**
 * NewGameActivity.java
 * 
 * Created on 25.05.2012 16:44:09
 */
package de.g18.scavengerhunt.activity;

import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

import de.g18.scavengerhunt.AppApplicationContext;
import de.g18.scavengerhunt.AppConstants;
import de.g18.scavengerhunt.R;
import de.g18.scavengerhunt.service.GeoDataGateway;
import de.g18.scavengerhunt.types.BattleZone;
import de.g18.scavengerhunt.utils.GameUtils;
import de.g18.scavengerhunt.utils.WebserviceUtil;

/**
 * This activity is shown, when a new game is created
 */
public class NewGameActivity extends MapActivity implements MapActivityInterface, OnSeekBarChangeListener {

    public String           LOG_TAG        = this.getClass().getSimpleName();

    private WebserviceUtil  webserviceUtil = null;

    private MapView         mapView        = null;

    private GeoDataGateway  geoDataGateway = null;

    private SeekBar         perimeterSize  = null;

    private BattleZone      battleZone     = null;

    private boolean        useGpsPos      = true;

    private EditText        txtGameName    = null;

    private Button          btnHostGame    = null;

    private Display         display		    = null;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.new_game);

        webserviceUtil = WebserviceUtil.getInstance();
        webserviceUtil.setContext(this);
        webserviceUtil.handleUserRegistration();

        txtGameName = (EditText) findViewById(R.id.txtGameName);
        btnHostGame = (Button) findViewById(R.id.btnHostGame);
        mapView = (MapView) findViewById(R.id.mapview);

        handlePerimeterSize((SeekBar) findViewById(R.id.perimeterSize), 2000, 10000);
        btnHostGame.setOnClickListener(hostGameClickHandler());       
        
        battleZone = new BattleZone();
        mapView.setBuiltInZoomControls(true);
        mapView.setSatellite(false);
        
        display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
    }

    /**
     * Click Handler for the host game button.
     * 
     * @return OnClickListener
     */
    private OnClickListener hostGameClickHandler() {
        return new OnClickListener() {

            @Override
            public void onClick(View view) {
                String gameName = txtGameName.getText().toString().trim();
                if (gameName.equals("")) {
					Toast.makeText(getApplicationContext(), getString(R.string.pleaseEnterSessionName), Toast.LENGTH_SHORT).show();
				} else {
					if (geoDataGateway != null) {
						GeoPoint currentPosition = GeoDataGateway.getCurrentPositionGeoPoint();
						if (currentPosition == null) {
							Toast.makeText(getApplicationContext(), getString(R.string.notificationNoGps), Toast.LENGTH_SHORT).show();
						} else {
							BattleZone battleZone = new BattleZone(currentPosition, perimeterSize.getProgress());
							battleZone.setName(gameName);
							if (webserviceUtil
									.createSession(gameName, AppApplicationContext.getUser().getId(), battleZone)) {
								GameUtils.showActivity(new GameMapActivity());
							} else {
								Toast.makeText(getApplicationContext(), getString(R.string.errorWhileCreatingSession), Toast.LENGTH_SHORT).show();
							}
						}
					}
				}
			}
        };
    }

    /**
     * Called automatically when the Activity has been created and will be visible to the user.
     */
    @Override
    protected void onStart() {
        super.onStart();

        // Give the ApplicationContext the current activity instance.
        AppApplicationContext.setActivity(this);

        // Start GPS
        if (useGpsPos && geoDataGateway == null) {
            startGPSDevice();
        }
    }

    /**
     * This override makes sure, that the device back button only intents to load the MainMenuActivity.
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            GameUtils.showActivity(new MainMenuActivity());
            return false;
        }

        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    /**
     * Starts using the gps device.
     */
    private void startGPSDevice() {
        geoDataGateway = new GeoDataGateway(this);
        geoDataGateway.start();
    }

    /**
     * Stops using the gps device.
     */
    private void stopGPSDevice() {
        if (geoDataGateway != null) {
            geoDataGateway.stop();
            geoDataGateway = null;
        }
    }

    /**
     * Will be called when the user changes the value of the SeekBar.
     * 
     * @param SeekBar seekBar
     * @param int progress
     * @param boolean isUser
     */
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean isUser) {
        battleZone.setRadiusInMeters(progress);
        mapView.invalidate();

        TextView txtPerimeterSizeValue = (TextView) findViewById(R.id.perimeterSizeValue);
        float value = (float) progress;
        String unit = "km";
        if (progress >= 1000) {
            value /= 1000;
            unit = "km";
        } else {
            unit = "m";
        }

        txtPerimeterSizeValue.setText(String.valueOf(value) + " " + unit);
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        // do nothing
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        // do nothing
    }

    /**
     * Handles intitialization of SeekBar to configure the perimeter size.
     * 
     * @param seekBar
     * @param progress
     * @param max
     */
    private void handlePerimeterSize(SeekBar seekBar, int progress, int max) {
        this.perimeterSize = seekBar;
        seekBar.setMax(max);
        seekBar.setProgress(progress);
        seekBar.setOnSeekBarChangeListener(this);
    }

    /**
     * Handles overlay update messages.
     */
    @Override
    public void onOverlayUpdate(Message msg) {
        switch (msg.what) {
            case AppConstants.UPDATE_OWN_POSITION:
            	GeoPoint currentOwnPosition = (GeoPoint) msg.obj;
                Log.d(LOG_TAG, "New GPS position detected [lat=" + currentOwnPosition.getLatitudeE6() + ", lng=" + currentOwnPosition.getLongitudeE6() + "]");
                
                // Set current position with specified radius of battlezone
                battleZone.setCircleCenter(currentOwnPosition);
                battleZone.setRadiusInMeters(perimeterSize.getProgress());
                if(battleZone.getCircleOverlay() != null && !mapView.getOverlays().contains(battleZone.getCircleOverlay())) {
                	// Show the battleZone on the map.
                	mapView.getOverlays().add(battleZone.getCircleOverlay());
                	
                	// Zoom to fit the BattleZone on screen once.
                    int zoomLevel = battleZone.getZoomLevelToFitZone(display.getWidth());
                    if(zoomLevel > mapView.getZoomLevel()) {
                    	mapView.getController().setZoom(zoomLevel);
                    	mapView.getController().animateTo(battleZone.getCircleCenter());
                    }
                }
                mapView.invalidate();
                break;
        }
    }

    /**
     * Called when the activity is no longer visible.
     */
    @Override
    protected void onStop() {
        super.onStop();
        stopGPSDevice();
    }
}
